﻿using FreedomX2.Core.IO;
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace FreedomX2.Core.Dynamic.Compiler
{
    public class Coder
    {
        public enum ResultType
        {
            DLL, Exe, Other
        }
        public static string[] CompilerFromFile(string ToPath, string[] filePath, string[] referencesStr = null, string[] resourcePath = null, string CompilerVersion = "v3.5", string mainClass = "", ResultType rt = ResultType.DLL)
        {
            List<string> strError = new List<string>();
            try
            {
                if (Directory.Exists(ToPath))
                    Directory.CreateDirectory(ToPath);
                CompilerParameters cp = new CompilerParameters();
                CodeDomProvider provider = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", CompilerVersion } });

                cp.ReferencedAssemblies.Add("System.dll");
                cp.ReferencedAssemblies.Add("System.Core.dll");
                if (resourcePath != null)
                    foreach (string str in resourcePath)
                    {
                        cp.EmbeddedResources.Add(str);
                    }
                if (referencesStr != null)
                    foreach (string str in referencesStr)
                    {
                        cp.ReferencedAssemblies.Add(str);
                    }
                cp.WarningLevel = 4;
                cp.IncludeDebugInformation = false;
                cp.OutputAssembly = ToPath;
                if (rt == ResultType.Exe)
                {
                    cp.GenerateExecutable = true;
                }
                else
                    cp.GenerateExecutable = false;
                if (mainClass != "")
                    cp.MainClass = mainClass;
                // 调用编译器
                CompilerResults cr = provider.CompileAssemblyFromFile(cp, filePath);
                if (cr.Errors.Count > 0)
                {
                    // 显示编译错误
                    foreach (CompilerError ce in cr.Errors)
                        strError.Add(ce.ToString());
                }
            }
            catch (Exception ex)
            {
                strError.Add(ex.Message);
            }
            return strError.ToArray();
        }
        public static string[] CompilerFromCode(string ToPath, string[] SourceCode, string[] referencesStr = null, string[] resourcePath = null, string CompilerVersion = "v3.5", string mainClass = "", ResultType rt = ResultType.DLL)
        {
            List<string> strError = new List<string>();
            try
            {
                if (Directory.Exists(ToPath))
                    Directory.CreateDirectory(ToPath);
                CompilerParameters cp = new CompilerParameters();
                CodeDomProvider provider = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", CompilerVersion } });

                cp.ReferencedAssemblies.Add("System.dll");
                cp.ReferencedAssemblies.Add("System.Core.dll");
                if (resourcePath != null)
                    foreach (string str in resourcePath)
                    {
                        cp.EmbeddedResources.Add(str);
                    }
                if (referencesStr != null)
                    foreach (string str in referencesStr)
                    {
                        cp.ReferencedAssemblies.Add(str);
                    }
                cp.WarningLevel = 4;
                cp.IncludeDebugInformation = false;
                cp.OutputAssembly = ToPath;
                if (rt == ResultType.Exe)
                {
                    cp.GenerateExecutable = true;
                }
                else
                    cp.GenerateExecutable = false;
                if (mainClass != "")
                    cp.MainClass = mainClass;
                // 调用编译器
                CompilerResults cr = provider.CompileAssemblyFromSource(cp, SourceCode);
                if (cr.Errors.Count > 0)
                {
                    // 显示编译错误
                    foreach (CompilerError ce in cr.Errors)
                        strError.Add(ce.ToString());
                }
            }
            catch (Exception ex)
            {
                strError.Add(ex.Message);
            }
            return strError.ToArray();
        }
    }
}
